package com.gzhryc.jdbc;

import com.gzhryc.jdbc.log.Logger;
import com.gzhryc.jdbc.models.ConnectInfo;
import org.apache.commons.lang3.StringUtils;

import java.io.*;
import java.lang.reflect.Constructor;
import java.util.Date;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MultiDBTools {

	private static Logger log = Logger.getLogger(MultiDBTools.class);

	private static ThreadLocal<String> TL_JdbcKey = new ThreadLocal<String>();

	private static ConcurrentHashMap<String, Object> Objects = new ConcurrentHashMap<String, Object>();

	public static String getJdbcKey() {
		return TL_JdbcKey.get();
	}

	public static void setJdbcKey(String jdbcKey) {
		TL_JdbcKey.set(jdbcKey);
	}

	public static void removeJdbcKey() {
		TL_JdbcKey.remove();
	}

	public static <T> T getService(Class<T> clazz) {
		return getService(clazz, true);
	}

	public static <T> T getService(Class<T> clazz, boolean isCreate) {
		String jdbcKey = TL_JdbcKey.get();
		if (StringUtils.isBlank(jdbcKey)) {
			jdbcKey = ConnectionFactory.getDefaultJdbcKey();
		}
		return getService(jdbcKey, clazz, isCreate);
	}

	public static <T> T getService(String jdbcKey, Class<T> clazz, boolean isCreate) {
		if (StringUtils.isNotBlank(jdbcKey)) {
			Object obj = Objects.get(jdbcKey);
			if (clazz.isInstance(obj)) {
				return clazz.cast(obj);
			}
			if (isCreate) {
				try {
					T entity = null;
					try {
						Constructor<T> constructor = clazz.getConstructor(String.class);
						entity = constructor.newInstance(jdbcKey);
					} catch (java.lang.reflect.InvocationTargetException e) {
						//重新来过一次
						try {
							Constructor<T> constructor = clazz.getConstructor(String.class);
							entity = constructor.newInstance(jdbcKey);
						}catch (Exception e1) {
							log.error(e.getMessage(), e1);
						}
					}catch (Exception e) {
						log.error(e.getMessage(), e);
					}
					if (entity != null) {
						Objects.put(jdbcKey, entity);
						return entity;
					}
				} catch (Exception e) {
					log.error(e.getMessage(), e);
				}
			}
		} else {
			log.error("获取{{0}}类失败，未传JdbcKey值", clazz.getName());
		}
		return null;
	}

	public static <T> T getService(Class<T> clazz, Date date) {
		String jdbcKey = TL_JdbcKey.get();
		if (StringUtils.isBlank(jdbcKey)) {
			jdbcKey = ConnectionFactory.getDefaultJdbcKey();
		}
		return getService(jdbcKey, clazz, date);
	}

	public static <T> T getService(String jdbcKey, Class<T> clazz, Date date) {
		if (StringUtils.isNotBlank(jdbcKey)) {
			try {
				T entity = null;
				try {
					Constructor<T> constructor = clazz.getConstructor(String.class, Date.class);
					entity = constructor.newInstance(jdbcKey, date);
				} catch (Exception e) {
					log.error(e.getMessage(), e);
				}
				return entity;
			} catch (Exception e) {
				log.error(e.getMessage(), e);
			}
		} else {
			log.error("获取{{0}}类失败，未传JdbcKey值", clazz.getName());
		}
		return null;
	}

	public static <T> void setService(T obj) {
		String jdbcKey = TL_JdbcKey.get();
		setService(jdbcKey, obj);
	}

	public static <T> void setService(String jdbcKey, T obj) {
		if (StringUtils.isNotBlank(jdbcKey)) {
			Objects.put(jdbcKey, obj);
		}
	}

	public static void initial(File dirFile) {
		if (dirFile.exists() && dirFile.isDirectory()) {
			File[] children = dirFile.listFiles();
			Pattern pat = Pattern.compile("jdbc(\\d+).properties");
			assert children != null;
			for (File file : children) {
				Matcher mat = pat.matcher(file.getName());
				if (mat.find()) {
					try {
						String id = mat.group(1);
						String jdbcKey = "hryc_" + id;

						Properties properties = new Properties();
						InputStream inStream = new FileInputStream(file);
						BufferedReader bf = new BufferedReader(new InputStreamReader(inStream, "UTF-8"));
						properties.load(bf);

						ConnectInfo info = new ConnectInfo(properties);
						ConnectionFactory.addDataSource(jdbcKey, info);

						log.info("加载" + file.getName() + "数据库连接配置信息");
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		}
	}
}
